package titt.service.content;

import java.io.File;

import titt.head.HTTPHead;
import titt.head.HeadFactory;
import titt.head.Header;
import titt.head.request.RequestHead;
import titt.head.request.form.FormHead;
import titt.io.IOFactory;
import titt.io.socket.in.TITTInputStream;
import titt.io.socket.out.LengthBufferedOutputStream;
import titt.io.socket.out.TITTOutputStream;
import titt.io.util.wrap.AutoWrapper;
import titt.util.io.pipe.StreamPiper;

public class NuderRequest {
		
	private TITTInputStream in;
	private FormHead fh;

	private Object o;
	private LengthBufferedOutputStream top, btm;
	
	public NuderRequest(Object o) {
		this(o, AutoWrapper.get().getMimeType(o));
	}
	
	public NuderRequest(Object o, String contentType) {
		this.o = o;
		
		String extra = "";
		if(o instanceof File) {
			extra = "; filename=\""+((File)o).getName()+"\"";
		}
		HTTPHead h = HeadFactory.createHead(new Header("Content-Disposition", "form-data; name=\"nuder\"" + extra), new Header("Content-Type", contentType));
		top = new LengthBufferedOutputStream();
		btm = new LengthBufferedOutputStream();

		try {	
			fh = new FormHead(0, HeadFactory.generateBoundary(), HeadFactory.EMPTY);
						
			top.writeLine(fh.getBounds()[0]);
			//TODO: shouldnt write line here !
//			top.writeLine();
			
			IOFactory.createHeadWriter(top).writeHead(h);
			top.flush();

			btm.writeLine();
			btm.writeLine(fh.getBounds()[1]);
			btm.flush();
		}
		catch(Exception e) {}

		fh = new FormHead(AutoWrapper.get().getLength(o) + top.getLength() + btm.getLength(), fh.getBoundary(), HeadFactory.EMPTY);
	}
	
	public NuderRequest(RequestHead head, TITTInputStream in) {
		fh = new FormHead(head);
		
		this.o = in;
		this.in = in;
	}
	
	public byte[][] getBoundaries() {
		return fh.getBounds();
	}
	
	public String getBoundary() {
		return fh.getBoundary();
	}
	
	public void writeTo(TITTOutputStream out) throws Exception {

		if(in == null) {
			top.writeTo(out);
			top.close();

			AutoWrapper.get().writeTo(null, out, o);

			btm.writeTo(out);
			btm.close();
		}
		else {
			StreamPiper p = IOFactory.createStreamPiper();
			p.pipe(in, out, fh.getContentLength());
		}
		out.flush();
	}
	
	public int getLength() {
		return fh.getContentLength();
	}
	
	public TITTInputStream getStream() {
		return in;
	}

	@SuppressWarnings("unchecked")
	public <T> T getContent() {
		return (T)o;
	}

}
